home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / widgets-mesa / src / MesaWorkstation.c < prev   
Encoding:
C/C++ Source or Header  |  1997-01-31  |  19.6 KB  |  831 lines

  1. /* MesaWorkstation.c -- Implementation file for the Mesa Workstation widget
  2.    Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de
  3.  
  4.    This library is free software; you can redistribute it and/or
  5.    modify it under the terms of the GNU Library General Public
  6.    License as published by the Free Software Foundation; either
  7.    version 2 of the License, or (at your option) any later version.
  8.  
  9.    This library is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU Library General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU Library General Public
  15.    License along with this library; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18.    $Id: MesaWorkstation.c,v 1.21 1996/09/30 00:21:07 ohl Exp $
  19.  */
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <math.h>
  24. #include <X11/IntrinsicP.h>
  25. #include <X11/StringDefs.h>
  26. #include <GL/glu.h>
  27. #include <GL/xmesa.h>
  28. #ifdef __GLX_MOTIF
  29. #include <GL/MesaMWorkstationP.h>
  30. #else
  31. #include <GL/MesaWorkstationP.h>
  32. #endif
  33.  
  34. #if STDC_HEADERS
  35. # include <string.h>
  36. #else
  37. # ifndef HAVE_STRCHR
  38. #  define strchr index
  39. #  define strrchr rindex
  40. # endif
  41. char *strchr (), *strrchr ();
  42. # ifndef HAVE_MEMCPY
  43. #  define memcpy(d, s, n) bcopy ((s), (d), (n))
  44. # endif
  45. # ifndef HAVE_MEMMOVE
  46. #  define memmove(d, s, n) bcopy ((s), (d), (n))
  47. # endif
  48. #endif
  49.  
  50. #ifndef M_PI
  51. #define M_PI 3.14159265358979323846
  52. #endif
  53.  
  54. #ifdef __GLX_MOTIF
  55. #define GLwDrawingAreaWidget       GLwMDrawingAreaWidget
  56. #define GLwDrawingAreaClassRec     GLwMDrawingAreaClassRec
  57. #define GLwDrawingAreaRec          GLwMDrawingAreaRec
  58. #define glwDrawingAreaClassRec     glwMDrawingAreaClassRec
  59. #define glwDrawingAreaWidgetClass  glwMDrawingAreaWidgetClass
  60. #define MesaDrawingAreaWidget      MesaMDrawingAreaWidget
  61. #define MesaDrawingAreaClassRec    MesaMDrawingAreaClassRec
  62. #define MesaDrawingAreaRec         MesaMDrawingAreaRec
  63. #define mesaDrawingAreaClassRec    mesaMDrawingAreaClassRec
  64. #define mesaDrawingAreaWidgetClass mesaMDrawingAreaWidgetClass
  65. #define MesaWorkstationWidget      MesaMWorkstationWidget
  66. #define MesaWorkstationClassRec    MesaMWorkstationClassRec
  67. #define MesaWorkstationRec         MesaMWorkstationRec
  68. #define mesaWorkstationClassRec    mesaMWorkstationClassRec
  69. #define mesaWorkstationWidgetClass mesaMWorkstationWidgetClass
  70. #define GLwPostObject           GLwMPostObject
  71. #define GLwUnpostObject           GLwMUnpostObject
  72. #define GLwUnpostAllObjects       GLwMUnpostAllObjects
  73. #define GLwBeginView           GLwMBeginView
  74. #define GLwEndView           GLwMEndView
  75. #define GLwPostViewList           GLwMPostViewList
  76. #define GLwPostViewMatrix       GLwMPostViewMatrix
  77. #define GLwPostCurrentView       GLwMPostCurrentView
  78. #define GLwUnpostView           GLwMUnpostView
  79. #define GLwSetPolarView           GLwMSetPolarView
  80. #define GLwGetViewList           GLwMGetViewList
  81. #define GLwGetViewMatrix       GLwMGetViewMatrix
  82. #define GLwBeginProjection       GLwMBeginProjection
  83. #define GLwEndProjection       GLwMEndProjection
  84. #define GLwPostProjectionList       GLwMPostProjectionList
  85. #define GLwPostProjectionMatrix       GLwMPostProjectionMatrix
  86. #define GLwPostCurrentProjection   GLwMPostCurrentProjection
  87. #define GLwUnpostProjection       GLwMUnpostProjection
  88. #define GLwSetFrustumProjection       GLwMSetFrustumProjection
  89. #define GLwSetOrthoProjection       GLwMSetOrthoProjection
  90. #define GLwGetProjectionList       GLwMGetProjectionList
  91. #define GLwGetProjectionMatrix       GLwMGetProjectionMatrix
  92. #define GLwRedrawObjects       GLwMRedrawObjects
  93. #define GLwPostView           GLwMPostView
  94. #define GLwGetView           GLwMGetView
  95. #define GLwPostProjection       GLwMPostProjection
  96. #define GLwGetProjection       GLwMGetProjection
  97. #endif
  98.  
  99. #define MesaProjection(_widget) \
  100.    (((MesaWorkstationWidget)_widget)->mesaWorkstation.projection)
  101. #define MesaView(_widget) \
  102.    (((MesaWorkstationWidget)_widget)->mesaWorkstation.view)
  103. #define MesaNextObject(_widget) \
  104.    (((MesaWorkstationWidget)_widget)->mesaWorkstation.next_object)
  105. #define MesaAllocatedObjects(_widget) \
  106.    (((MesaWorkstationWidget)_widget)->mesaWorkstation.allocated_objects)
  107. #define MesaObjects(_widget) \
  108.    (((MesaWorkstationWidget)_widget)->mesaWorkstation.objects)
  109.  
  110.  
  111. /* Private utility functions. */
  112.  
  113.  
  114. /* Resources. */
  115.  
  116.  
  117. /* Actions and their translations. */
  118.  
  119. static void
  120. Projection (Widget w, XEvent *event, String *argv, Cardinal *argc)
  121. {
  122.   LOG (w);
  123.  
  124.   if (*argc == 0)
  125.     return;
  126.  
  127.   if ((MesaProjection(w).type != FRUSTUM)
  128.       && (MesaProjection(w).type != ORTHO))
  129.     return;
  130.  
  131.   switch (*argv[0])
  132.     {
  133.     case 'p':
  134.       MesaProjection(w).type = FRUSTUM;
  135.       break;
  136.     case 'o':
  137.       MesaProjection(w).type = ORTHO;
  138.       break;
  139.     case 'l':
  140.       MesaProjection(w).u.vol.left *= 1.1;
  141.       break;
  142.     case 'L':
  143.       MesaProjection(w).u.vol.left /= 1.1;
  144.       break;
  145.     case 'r':
  146.       MesaProjection(w).u.vol.right *= 1.1;
  147.       break;
  148.     case 'R':
  149.       MesaProjection(w).u.vol.right /= 1.1;
  150.       break;
  151.     case 'b':
  152.       MesaProjection(w).u.vol.bottom *= 1.1;
  153.       break;
  154.     case 'B':
  155.       MesaProjection(w).u.vol.bottom /= 1.1;
  156.       break;
  157.     case 't':
  158.       MesaProjection(w).u.vol.top *= 1.1;
  159.       break;
  160.     case 'T':
  161.       MesaProjection(w).u.vol.top /= 1.1;
  162.       break;
  163.     case 'n':
  164.       MesaProjection(w).u.vol.near *= 1.1;
  165.       break;
  166.     case 'N':
  167.       MesaProjection(w).u.vol.near /= 1.1;
  168.       break;
  169.     case 'f':
  170.       MesaProjection(w).u.vol.far *= 1.1;
  171.       break;
  172.     case 'F':
  173.       MesaProjection(w).u.vol.far /= 1.1;
  174.       break;
  175.     case 'a':
  176.       MesaProjection(w).u.vol.left *= 1.1;
  177.       MesaProjection(w).u.vol.right *= 1.1;
  178.       MesaProjection(w).u.vol.bottom *= 1.1;
  179.       MesaProjection(w).u.vol.top *= 1.1;
  180.       break;
  181.     case 'A':
  182.       MesaProjection(w).u.vol.left /= 1.1;
  183.       MesaProjection(w).u.vol.right /= 1.1;
  184.       MesaProjection(w).u.vol.bottom /= 1.1;
  185.       MesaProjection(w).u.vol.top /= 1.1;
  186.       break;
  187.     }
  188.  
  189.   GLwRedrawObjects (w);
  190. }
  191.  
  192. static void
  193. Move (Widget w, XEvent *event, String *argv, Cardinal *argc)
  194. {
  195.   double scale = 0.01;
  196.   LOG (w);
  197.  
  198.   if (*argc == 0)
  199.     return;
  200.  
  201.   if (MesaView(w).type != POLAR)
  202.     return;
  203.  
  204.   if (*argc >= 2)
  205.     scale *= atof (argv[1]);
  206.  
  207.   switch (*argv[0])
  208.     {
  209.     case '+':
  210.       MesaView(w).u.polar.r /= 1.1;
  211.       break;
  212.     case '-':
  213.       MesaView(w).u.polar.r *= 1.1;
  214.       break;
  215.     case 'l':
  216.       MesaView(w).u.polar.phi += scale * M_PI;
  217.       break;
  218.     case 'r':
  219.       MesaView(w).u.polar.phi -= scale * M_PI;
  220.       break;
  221.     case 'u':
  222.       MesaView(w).u.polar.theta -= scale * M_PI;
  223.       break;
  224.     case 'd':
  225.       MesaView(w).u.polar.theta += scale * M_PI;
  226.       break;
  227.     }
  228.  
  229.   GLwRedrawObjects (w);
  230. }
  231.  
  232. static XtActionsRec actions[] =
  233. {
  234.   /* {name, procedure} */
  235.   {"Move", Move },
  236.   {"Projection", Projection },
  237. };
  238.  
  239. static char translations[] =
  240. #ifdef __GLX_MOTIF
  241. "~Shift<Key>osfLeft: Move(l)\n\
  242. Shift<Key>osfLeft: Move(l,10)\n\
  243. ~Shift<Key>osfRight: Move(r)\n\
  244. Shift<Key>osfRight: Move(r,10)\n\
  245. ~Shift<Key>osfUp: Move(u)\n\
  246. Shift<Key>osfUp: Move(u,10)\n\
  247. ~Shift<Key>osfDown: Move(d)\n\
  248. Shift<Key>osfDown: Move(d,10)\n\
  249. ~Shift<Key>Left: Move(l)\n\
  250. Shift<Key>Left: Move(l,10)\n\
  251. ~Shift<Key>Right: Move(r)\n\
  252. Shift<Key>Right: Move(r,10)\n\
  253. ~Shift<Key>Up: Move(u)\n\
  254. Shift<Key>Up: Move(u,10)\n\
  255. ~Shift<Key>Down: Move(d)\n\
  256. Shift<Key>Down: Move(d,10)\n\
  257. <Key>plus: Move(+)\n\
  258. <Key>minus: Move(-)\n\
  259. ~Shift<Key>l: Projection(l)\n\
  260. Shift<Key>l: Projection(L)\n\
  261. ~Shift<Key>r: Projection(r)\n\
  262. Shift<Key>r: Projection(R)\n\
  263. ~Shift<Key>b: Projection(b)\n\
  264. Shift<Key>b: Projection(B)\n\
  265. ~Shift<Key>t: Projection(t)\n\
  266. Shift<Key>t: Projection(T)\n\
  267. ~Shift<Key>n: Projection(n)\n\
  268. Shift<Key>n: Projection(N)\n\
  269. ~Shift<Key>f: Projection(f)\n\
  270. Shift<Key>f: Projection(F)\n\
  271. ~Shift<Key>a: Projection(a)\n\
  272. Shift<Key>a: Projection(A)\n\
  273. <Key>p: Projection(p)\n\
  274. <Key>o: Projection(o)\n";
  275. #else /* __GLX_MOTIF */
  276. "~Shift<Key>Left: Move(l)\n\
  277. Shift<Key>Left: Move(l,10)\n\
  278. ~Shift<Key>Right: Move(r)\n\
  279. Shift<Key>Right: Move(r,10)\n\
  280. ~Shift<Key>Up: Move(u)\n\
  281. Shift<Key>Up: Move(u,10)\n\
  282. ~Shift<Key>Down: Move(d)\n\
  283. Shift<Key>Down: Move(d,10)\n\
  284. <Key>plus: Move(+)\n\
  285. <Key>minus: Move(-)\n\
  286. ~Shift<Key>l: Projection(l)\n\
  287. Shift<Key>l: Projection(L)\n\
  288. ~Shift<Key>r: Projection(r)\n\
  289. Shift<Key>r: Projection(R)\n\
  290. ~Shift<Key>b: Projection(b)\n\
  291. Shift<Key>b: Projection(B)\n\
  292. ~Shift<Key>t: Projection(t)\n\
  293. Shift<Key>t: Projection(T)\n\
  294. ~Shift<Key>n: Projection(n)\n\
  295. Shift<Key>n: Projection(N)\n\
  296. ~Shift<Key>f: Projection(f)\n\
  297. Shift<Key>f: Projection(F)\n\
  298. ~Shift<Key>a: Projection(a)\n\
  299. Shift<Key>a: Projection(A)\n\
  300. <Key>p: Projection(p)\n\
  301. <Key>o: Projection(o)\n";
  302. #endif /* __GLX_MOTIF */
  303.  
  304.  
  305. /* Basic widget methods.  */
  306.  
  307. #define OBJECT_CHUNK_SIZE 10
  308.  
  309. static void
  310. Initialize (Widget request, Widget new, ArgList args, Cardinal * num_args)
  311. {
  312.   LOG (new);
  313.   MesaAllocatedObjects (new) = OBJECT_CHUNK_SIZE;
  314.   MesaObjects (new) = (GLuint *)
  315.     XtCalloc (MesaAllocatedObjects (new), sizeof (GLuint));
  316.   MesaNextObject (new) = MesaObjects (new);
  317.   MesaView(new).type = NOVIEW;
  318.   MesaView(new).list = 0;
  319.   MesaProjection(new).type = NOPROJ;
  320.   MesaProjection(new).list = 0;
  321. }
  322.  
  323. #if 0
  324. static void
  325. Realize (Widget w, XtValueMask * mask,
  326.      XSetWindowAttributes * attr)
  327. {
  328.   LOG (w);
  329.   (XtSuperclass (w)->core_class.realize) (w, mask, attr);
  330. }
  331. #endif
  332.  
  333. static void
  334. Destroy (Widget w)
  335. {
  336.   LOG (w);
  337.   XtFree ((char *) MesaObjects (w));
  338. }
  339.  
  340. static void
  341. Redisplay (Widget w, XEvent *event, Region region)
  342. {
  343.   LOG (w);
  344.   if (event->xexpose.count == 0)    /* last Expose event */
  345.     GLwRedrawObjects (w);
  346. }
  347.  
  348.  
  349. /* Now use all these methods in the widget class record.  */
  350.  
  351. MesaWorkstationClassRec mesaWorkstationClassRec =
  352. {
  353.   {
  354.     /* superclass            */ (WidgetClass) &mesaDrawingAreaClassRec,
  355. #ifdef __GLX_MOTIF
  356.     /* class_name            */ "MesaMWorkstation",
  357. #else
  358.     /* class_name            */ "MesaWorkstation",
  359. #endif
  360.     /* widget_size           */ sizeof (MesaWorkstationRec),
  361.     /* class_initialize      */ NULL,
  362.     /* class_part_initialize */ NULL,
  363.     /* class_inited          */ FALSE,
  364.     /* initialize            */ Initialize,
  365.     /* initialize_hook       */ NULL,
  366.     /* realize               */ XtInheritRealize,
  367.     /* actions               */ actions,
  368.     /* num_actions           */ XtNumber (actions),
  369.     /* resources             */ NULL,
  370.     /* num_resources         */ 0,
  371.     /* xrm_class             */ NULLQUARK,
  372.     /* compress_motion       */ TRUE,
  373.     /* compress_exposure     */ TRUE,
  374.     /* compress_enterleave   */ TRUE,
  375.     /* visible_interest      */ FALSE,
  376.     /* destroy               */ Destroy,
  377.     /* resize                */ XtInheritResize,
  378.     /* expose                */ Redisplay,
  379.     /* set_values            */ NULL,
  380.     /* set_values_hook       */ NULL,
  381.     /* set_values_almost     */ XtInheritSetValuesAlmost,
  382.     /* get_values_hook       */ NULL,
  383.     /* accept_focus          */ NULL,
  384.     /* version               */ XtVersion,
  385.     /* callback_private      */ NULL,
  386.     /* tm_table              */ translations,
  387.     /* query_geometry        */ XtInheritQueryGeometry,
  388.     /* display_accelerator   */ XtInheritDisplayAccelerator,
  389.     /* extension             */ NULL
  390.   },
  391. #ifdef __GLX_MOTIF
  392.   { /* XmPrimitive fields */
  393.     /* border_highlight      */ (XtWidgetProc) _XtInherit,
  394.     /* border_unhighlight    */ (XtWidgetProc) _XtInherit,
  395.     /* translations          */ XtInheritTranslations,
  396.     /* arm_and_activate      */ NULL,
  397.     /* get_resources         */ NULL,
  398.     /* num get_resources     */ 0,
  399.     /* extension             */ NULL,
  400.   },
  401. #endif /* __GLX_MOTIF */
  402.   { /* MesaDrawingArea fields*/
  403.     /* RCS_id                */ NULL
  404.   },
  405.   { /* MesaWorkstation fields*/
  406.     /* RCS_id                */
  407.     "@(#) $Id: MesaWorkstation.c,v 1.21 1996/09/30 00:21:07 ohl Exp $"
  408.   }
  409. };
  410. WidgetClass mesaWorkstationWidgetClass
  411.   = (WidgetClass) & mesaWorkstationClassRec;
  412.  
  413.  
  414. /* More private utility functions. */
  415.  
  416. static int
  417. is_workstation (Widget w)
  418. {
  419.   if (XtClass (w) != mesaWorkstationWidgetClass)
  420.     {
  421.       XtAppError (XtWidgetToApplicationContext (w),
  422. #ifndef __GLX_MOTIF
  423.           "Not a Mesa Workstation!");
  424. #else
  425.           "Not a Mesa/Motif Workstation!");
  426. #endif
  427.       return 0;
  428.     }
  429.   else
  430.     return 1;
  431. }
  432.  
  433. static void
  434. mesa_frustum (volume v)
  435. {
  436.   glFrustum (v.left, v.right, v.bottom, v.top, v.near, v.far);
  437. }
  438.  
  439. static void
  440. mesa_ortho (volume v)
  441. {
  442.   glOrtho (v.left, v.right, v.bottom, v.top, v.near, v.far);
  443. }
  444.  
  445. static void
  446. mesa_look_at (look_at l)
  447. {
  448.   gluLookAt (l.eyex, l.eyex, l.eyez,
  449.          l.ctrx, l.ctrx, l.ctrz,
  450.          l.upx, l.upx, l.upz);
  451. }
  452.  
  453.  
  454. static void
  455. mesa_polar (polar p)
  456. {
  457.   GLdouble r, sin_th, cos_th, sin_phi, cos_phi, u_sin_th, u_cos_th;
  458.   r = p.r;
  459.   sin_th = sin (p.theta);
  460.   cos_th = cos (p.theta);
  461.   sin_phi = sin (p.phi);
  462.   cos_phi = cos (p.phi);
  463.   u_sin_th = cos_th;
  464.   u_cos_th = -sin_th;
  465.   gluLookAt (r*sin_th*cos_phi, r*cos_th, r*sin_th*sin_phi,
  466.          0.0, 0.0, 0.0,
  467.          u_sin_th*cos_phi, u_cos_th, u_sin_th*sin_phi);
  468. }
  469.  
  470.  
  471. /* Exported utilility functions.  */
  472. void
  473. GLwPostObject (Widget w, GLuint object)
  474. {
  475.   if (is_workstation (w))
  476.     {
  477.       if (MesaNextObject (w) > MesaObjects (w) + MesaAllocatedObjects (w))
  478.     {
  479.       MesaAllocatedObjects (w) += OBJECT_CHUNK_SIZE;
  480.       MesaObjects (w) = (GLuint *)
  481.         XtRealloc ((char *) MesaObjects (w),
  482.                sizeof (GLuint) * MesaAllocatedObjects (w));
  483.     }
  484.       *(MesaNextObject(w)++) = object;
  485.     }
  486. }
  487.  
  488. void
  489. GLwUnpostObject (Widget w, GLuint object)
  490. {
  491.   if (is_workstation (w))
  492.     {
  493.       GLuint *p;
  494.       for (p = MesaObjects (w); p < MesaNextObject (w); p++)
  495.     if (*p == object)
  496.       {
  497.         memmove (p, p + 1,
  498.              sizeof (GLuint) * (MesaNextObject (w) - p - 1));
  499.         MesaNextObject(w)--;
  500.         break;
  501.       }
  502.     }
  503. }
  504.  
  505. void
  506. GLwUnpostAllObjects (Widget w)
  507. {
  508.   if (is_workstation (w))
  509.     MesaNextObject (w) = MesaObjects (w);
  510. }
  511.  
  512. void
  513. GLwBeginView (Widget w)
  514. {
  515.   if (is_workstation (w))
  516.     {
  517.       MesaView(w).type = VIEW_LIST;
  518.       if (!glIsList (MesaView(w).list))
  519.     MesaView(w).list = glGenLists (1);
  520.       glNewList (MesaView(w).list, GL_COMPILE);
  521.     }
  522. }
  523.  
  524. void
  525. GLwEndView (void)
  526. {
  527.   glEndList ();
  528. }
  529.  
  530. void
  531. GLwPostViewList (Widget w, GLuint view)
  532. {
  533.   if (is_workstation (w))
  534.     {
  535.       MesaView(w).type = VIEW_LIST;
  536.       MesaView(w).list = view;
  537.     }
  538. }
  539.  
  540. void
  541. GLwPostViewMatrix (Widget w, GLdouble *m)
  542. {
  543.   if (is_workstation (w))
  544.     {
  545.       MesaView(w).type = VIEW_MATRIX;
  546.       memcpy (MesaView(w).u.m, m, sizeof (MesaView(w).u.m));
  547.     }
  548. }
  549.  
  550. void
  551. GLwPostCurrentView (Widget w)
  552. {
  553.   if (is_workstation (w))
  554.     {
  555.       MesaView(w).type = VIEW_MATRIX;
  556.       glGetDoublev (GL_MODELVIEW_MATRIX, MesaView(w).u.m);
  557.     }
  558. }
  559.  
  560. void
  561. GLwUnpostView (Widget w)
  562. {
  563.   if (is_workstation (w))
  564.     MesaView(w).type = NOVIEW;
  565. }
  566.  
  567. void
  568. GLwSetPolarView (Widget w, GLdouble r, GLdouble theta, GLdouble phi)
  569. {
  570.   if (is_workstation (w))
  571.     {
  572.       MesaView(w).type = POLAR;
  573.       MesaView(w).u.polar.r = r;
  574.       MesaView(w).u.polar.theta = theta;
  575.       MesaView(w).u.polar.phi = phi;
  576.     }
  577. }
  578.  
  579. GLuint
  580. GLwGetViewList (Widget w)
  581. {
  582.   if (is_workstation (w))
  583.     {
  584.       if (MesaView(w).type == VIEW_LIST)
  585.     return MesaView(w).list;
  586.     }
  587.   return 0;
  588. }
  589.  
  590. int
  591. GLwGetViewMatrix (Widget w, GLdouble *m)
  592. {
  593.   if (is_workstation (w))
  594.     {
  595.       if (MesaView(w).type == VIEW_MATRIX)
  596.     memcpy (m, MesaView(w).u.m, sizeof (MesaView(w).u.m));
  597.       return 1;
  598.     }
  599.   return 0;
  600. }
  601.  
  602. void
  603. GLwBeginProjection (Widget w)
  604. {
  605.   if (is_workstation (w))
  606.     {
  607.       MesaProjection(w).type = PROJ_LIST;
  608.       if (!glIsList (MesaProjection(w).list))
  609.     MesaProjection(w).list = glGenLists (1);
  610.       glNewList (MesaProjection(w).list, GL_COMPILE);
  611.     }
  612. }
  613.  
  614. void
  615. GLwEndProjection (void)
  616. {
  617.   glEndList ();
  618. }
  619.  
  620. void
  621. GLwPostProjectionList (Widget w, GLuint proj)
  622. {
  623.   if (is_workstation (w))
  624.     {
  625.       MesaProjection(w).type = PROJ_LIST;
  626.       MesaProjection(w).list = proj;
  627.     }
  628. }
  629.  
  630. void
  631. GLwPostProjectionMatrix (Widget w, GLdouble *m)
  632. {
  633.   if (is_workstation (w))
  634.     {
  635.       MesaProjection(w).type = PROJ_MATRIX;
  636.       memcpy (MesaProjection(w).u.m, m, sizeof (MesaProjection(w).u.m));
  637.     }
  638. }
  639.  
  640. void
  641. GLwPostCurrentProjection (Widget w)
  642. {
  643.   if (is_workstation (w))
  644.     {
  645.       MesaProjection(w).type = PROJ_MATRIX;
  646.       glGetDoublev (GL_PROJECTION_MATRIX, MesaProjection(w).u.m);
  647.     }
  648. }
  649.  
  650. void
  651. GLwUnpostProjection (Widget w)
  652. {
  653.   if (is_workstation (w))
  654.     MesaProjection(w).type = NOPROJ;
  655. }
  656.  
  657. void
  658. GLwSetFrustumProjection (Widget w,
  659.              GLdouble left, GLdouble right,
  660.              GLdouble bottom, GLdouble top,
  661.              GLdouble near, GLdouble far)
  662. {
  663.   if (is_workstation (w))
  664.     {
  665.       MesaProjection(w).type = FRUSTUM;
  666.       MesaProjection(w).u.vol.left = left;
  667.       MesaProjection(w).u.vol.right = right;
  668.       MesaProjection(w).u.vol.bottom = bottom;
  669.       MesaProjection(w).u.vol.top = top;
  670.       MesaProjection(w).u.vol.near = near;
  671.       MesaProjection(w).u.vol.far = far;
  672.     }
  673. }
  674.  
  675. void
  676. GLwSetOrthoProjection (Widget w,
  677.              GLdouble left, GLdouble right,
  678.              GLdouble bottom, GLdouble top,
  679.              GLdouble near, GLdouble far)
  680. {
  681.   if (is_workstation (w))
  682.     {
  683.       MesaProjection(w).type = ORTHO;
  684.       MesaProjection(w).u.vol.left = left;
  685.       MesaProjection(w).u.vol.right = right;
  686.       MesaProjection(w).u.vol.bottom = bottom;
  687.       MesaProjection(w).u.vol.top = top;
  688.       MesaProjection(w).u.vol.near = near;
  689.       MesaProjection(w).u.vol.far = far;
  690.     }
  691. }
  692.  
  693. GLuint
  694. GLwGetProjectionList (Widget w)
  695. {
  696.   if (is_workstation (w))
  697.     {
  698.       if (MesaProjection(w).type == PROJ_LIST)
  699.     return MesaProjection(w).list;
  700.     }
  701.   return 0;
  702. }
  703.  
  704. int
  705. GLwGetProjectionMatrix (Widget w, GLdouble *m)
  706. {
  707.   if (is_workstation (w))
  708.     {
  709.       if (MesaProjection(w).type == PROJ_MATRIX)
  710.     memcpy (m, MesaProjection(w).u.m, sizeof (MesaProjection(w).u.m));
  711.       return 1;
  712.     }
  713.   return 0;
  714. }
  715.  
  716. void
  717. GLwRedrawObjects (Widget w)
  718. {
  719.   if (is_workstation (w))
  720.     {
  721.       XMesaBuffer buffer = XMesaGetCurrentBuffer ();
  722.       XMesaContext context = XMesaGetCurrentContext ();
  723.       XMesaMakeCurrent (MesaContext (w), MesaBuffer (w));
  724.       if (MesaProjection(w).type != NOPROJ)
  725.     {
  726.       glMatrixMode (GL_PROJECTION);
  727.       glPushMatrix ();
  728.       glLoadIdentity ();
  729.     }
  730.       switch (MesaProjection(w).type)
  731.     {
  732.     case PROJ_MATRIX:
  733.       glLoadMatrixd (MesaProjection(w).u.m);
  734.       break;
  735.     case PROJ_LIST:
  736.       if (!glIsList (MesaProjection(w).list))
  737.         XtAppWarning (XtWidgetToApplicationContext (w),
  738.               "Invalid projection list!");
  739.       else
  740.         glCallList (MesaProjection(w).list);
  741.       break;
  742.     case FRUSTUM:
  743.       mesa_frustum (MesaProjection(w).u.vol);
  744.       break;
  745.     case ORTHO:
  746.       mesa_ortho (MesaProjection(w).u.vol);
  747.       break;
  748.     case NOPROJ:
  749.       break;
  750.     }
  751.       glMatrixMode (GL_MODELVIEW);
  752.       glPushMatrix ();
  753.       {
  754.     GLuint *obj;
  755.     glLoadIdentity ();
  756.     switch (MesaView(w).type)
  757.       {
  758.       case PROJ_MATRIX:
  759.         glLoadMatrixd (MesaView(w).u.m);
  760.         break;
  761.       case PROJ_LIST:
  762.         if (!glIsList (MesaView(w).list))
  763.           XtAppWarning (XtWidgetToApplicationContext (w),
  764.                 "Invalid view list!");
  765.         else
  766.           glCallList (MesaView(w).list);
  767.         break;
  768.       case LOOK_AT:
  769.         mesa_look_at (MesaView(w).u.look_at);
  770.         break;
  771.       case POLAR:
  772.         mesa_polar (MesaView(w).u.polar);
  773.         break;
  774.       case NOVIEW:
  775.         break;
  776.       }
  777.     for (obj = MesaObjects (w); obj < MesaNextObject (w); obj++)
  778.       {
  779.         if (!glIsList (*obj))
  780.           XtAppWarning (XtWidgetToApplicationContext (w),
  781.                 "Invalid object list!");
  782.         else
  783.           {
  784.         glPushMatrix ();
  785.           glCallList (*obj);
  786.         glPopMatrix ();
  787.           }
  788.       }         
  789.       }
  790.       glPopMatrix ();
  791.       if (MesaProjection(w).type != NOVIEW)
  792.     {
  793.       glMatrixMode (GL_PROJECTION);
  794.       glPopMatrix ();
  795.       glMatrixMode (GL_MODELVIEW);
  796.     }
  797.       glFinish ();
  798.       XMesaSwapBuffers (buffer);
  799.       XMesaMakeCurrent (context, buffer);
  800.     }
  801. }
  802.  
  803. /* obsolete aliases: */
  804.  
  805. void
  806. GLwPostView (Widget w, GLuint view)
  807. {
  808.   GLwPostViewList (w, view);
  809. }
  810.  
  811. GLuint
  812. GLwGetView (Widget w)
  813. {
  814.   return GLwGetViewList (w);
  815. }
  816.  
  817. void
  818. GLwPostProjection (Widget w, GLuint proj)
  819. {
  820.   GLwPostProjectionList (w, proj);
  821. }
  822.  
  823. GLuint
  824. GLwGetProjection (Widget w)
  825. {
  826.   return GLwGetProjectionList (w);
  827. }
  828.  
  829. /* The End. */
  830.  
  831.